local class = require 'hump.class'

local G = 6.67e-7

--mass in kg
SpacePhysicsItem = class{
  function(self, mass, cx, cy)
    self.cx = cx
    self.cy = cy
    self.mass = mass
    self.vx = 0
    self.vy = 0
    self.maxSpeed = nil
  end
}
			 
function SpacePhysicsItem:update(dt)
  local velocity = math.sqrt(self.vx*self.vx+self.vy*self.vy)
  if self.maxSpeed and velocity > self.maxSpeed then
    self.vx = self.vx * self.maxSpeed / velocity
    self.vy = self.vy * self.maxSpeed / velocity
  end
  self.cx = self.cx + self.vx*dt
  self.cy = self.cy + self.vy*dt
end

function SpacePhysicsItem:accelerate(ax, ay, dt)
  self.vx = self.vx+ax*dt
  self.vy = self.vy+ay*dt
end

function SpacePhysicsItem:stop()
  self.vx = 0
  self.vy = 0
end

function SpacePhysicsItem:setMaximumSpeed(speed)
  self.maxSpeed = speed
end

function SpacePhysicsItem:maximumSpeed()
  return self.maxSpeed
end

function SpacePhysicsItem:center()
  return self.cx, self.cy
end

function SpacePhysicsItem:velocity()
  return self.vx, self.vy
end

SpacePhysics = class{
  function(self)
    self.items = {}
  end
}

function SpacePhysics:update(dt)
  for i = 1,#self.items do --take gravity into account
    for j = i+1,#self.items do
      local obj1 = self.items[i]
      local obj2 = self.items[j]
      local r = math.sqrt((obj1.cx-obj2.cx)^2 + (obj1.cy-obj2.cy)^2)
      local f = G * obj1.mass * obj2.mass / r^2
      local fx = f*(obj1.cx-obj2.cx)/r
      local fy = f*(obj1.cy-obj2.cy)/r
      
      if obj1.mass > obj2.mass then
        obj2:accelerate(fx, fy, dt)
      else
        obj1:accelerate(-fx, -fy, dt)
      end
    end
  end
  
  for i = 1,#self.items do --now update each item
    self.items[i]:update(dt)
  end
end
		     
function SpacePhysics:newItem(mass, cx, cy)
  local item = SpacePhysicsItem(mass, cx, cy)
  self.items[#self.items+1] = item
  return item
end

function SpacePhysics:removeItem(item)
  for i = 1,#self.items do
    if item == self.items[i] then
      table.remove(self.items, i)
    end
  end
end
